package cn.mvc.web.learn;

import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.method.support.InvocableHandlerMethod;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.*;
import org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
import java.util.Map;

/**
 * 详细介绍 SpringMVC 的执行流程，除此之外这个类没有实际作用。
 * <p>
 * 流程图:
 * 1.用户请求->DispatcherServlet
 * 2.DispatcherServlet<->查询HandlerMapping，返回HandlerExecutionChain
 * 3.DispatcherServlet->(请求执行Handler)HandlerAdapter
 * 4.HandlerAdapter<->执行Handler，返回ModelAndView
 * 5.HandlerAdapter->(返回ModelAndView)DispatcherServlet
 * 6.DispatcherServlet<->(请求解析视图)ViewResolver，返回View对象
 * 7.DispatcherServlet<->(请求渲染视图)模板引擎，渲染后返回
 * 8.DispatcherServlet->响应用户
 *
 * @author yexi
 */
public class SpringMvcHandleProcess {

    /**
     * DispatcherServlet: 前端控制器
     * 用户请求到达前端控制器，它就相当于 mvc 模式中的 c，dispatcherServlet 是整个流程控制的中心，由 它调用其它组件处理用户的请求，
     * dispatcherServlet 的存在降低了组件之间的耦合性。
     *
     * @see FrameworkServlet#service(HttpServletRequest, HttpServletResponse) 继承了 HttpServlet
     * @see FrameworkServlet#processRequest(HttpServletRequest, HttpServletResponse) 处理请求
     * @see DispatcherServlet#doService(HttpServletRequest, HttpServletResponse)
     * @see DispatcherServlet#doDispatch(HttpServletRequest, HttpServletResponse) 在这个方法里面就包含了流程的全部元素
     * @see DispatcherServlet#defaultStrategies 即便不自定义HandlerMapping、HandleAdapter时，也会采用的默认策略实现。
     * 读取配置文件地址: spring-webmvc-{指定版本}.jar!\org\springframework\web\servlet\DispatcherServlet.properties
     */
    public void dispatcherServlet() {
    }

    /**
     * HandlerMapping: 处理器映射器
     * HandlerMapping 负责根据用户请求找到 Handler(处理器)，SpringMVC 提供了不同的映射器实现不同的 映射方式，例如：配置文件方式，实现接口方式，注解方式等。
     * 具体实现类:
     * RequestMappingHandlerMapping —— 它会处理 @RequestMapping 注解，并将其注册到请求映射表中。用于将请求映射到具体的处理器方法上。
     *
     * @see DispatcherServlet#getHandler(HttpServletRequest)
     * DispatcherServlet与 HandlerMapping 的交互，返回 HandlerExecutionChain(处理器执行链)
     */
    public void handlerMapping() {
    }

    /**
     * Handler: 处理器 (自己定义的Controller处理单元)
     * 它就是我们开发中要编写的具体业务控制器。由 DispatcherServlet 把用户请求转发到 Handler。由 Handler 对具体的用户请求进行处理。
     *
     * @see HandlerExecutionChain#getHandler() DispatcherServlet通过 HandlerExecutionChain 返回 Handler
     */
    public void handler() {
    }

    /**
     * HandleAdapter：处理器适配器
     * 通过 HandlerAdapter 对处理器进行执行，这是适配器模式的应用，通过扩展适配器可以对更多类型的处理器进行执行
     * 具体实现类:
     * RequestMappingHandlerAdapter —— 确定调用哪个类的哪个方法，并且构造方法参数，返回值。用于负责调用处理器方法，并将其返回值转换成一个合适的响应结果对象。
     *
     * @see DispatcherServlet#getHandlerAdapter(Object)
     * @see HandlerAdapter#handle(HttpServletRequest, HttpServletResponse, Object) 处理，返回 ModelAndView
     * @see AbstractHandlerMethodAdapter#handleInternal(HttpServletRequest, HttpServletResponse, HandlerMethod)
     * @see RequestMappingHandlerAdapter#handleInternal(HttpServletRequest, HttpServletResponse, HandlerMethod)
     * @see RequestMappingHandlerAdapter#invokeHandlerMethod(HttpServletRequest, HttpServletResponse, HandlerMethod)
     * @see ServletInvocableHandlerMethod#invokeAndHandle(ServletWebRequest, ModelAndViewContainer, Object...)
     * @see InvocableHandlerMethod#invokeForRequest(NativeWebRequest, ModelAndViewContainer, Object...)
     * @see InvocableHandlerMethod#doInvoke(Object...) 通过反射通过 Method 对象以及作为 bean 的 Controller 调用到方法内部细节中
     */
    public void handlerAdapter() {
    }

    /**
     * ViewResolver：视图解析器
     * ViewResolver 负责将处理结果生成 View 视图，View Resolver 首先根据逻辑视图名解析成物理视图名 即具体的页面地址，再生成 View 视图对象，
     * 最后对 View 进行渲染将处理结果通过页面展示给用户。
     *
     * @see DispatcherServlet#processDispatchResult(HttpServletRequest, HttpServletResponse, HandlerExecutionChain, ModelAndView, Exception)
     * @see DispatcherServlet#render(ModelAndView, HttpServletRequest, HttpServletResponse)
     * @see DispatcherServlet#resolveViewName(String, Map, Locale, HttpServletRequest)  视图解析器处理 viewName 返回 View
     */
    public void viewResolver() {
    }

    /**
     * HandlerExceptionResolver: 异常处理器适配器
     * 具体实现类:
     * ExceptionHandlerExceptionResolver：用于解决处理器方法抛出异常的情况。
     *
     * @see DispatcherServlet#processDispatchResult(HttpServletRequest, HttpServletResponse, HandlerExecutionChain, ModelAndView, Exception)
     */
    public void handlerExceptionResolver() {
    }

    /**
     * View：视图
     * SpringMVC 框架提供了很多的 View 视图类型的支持，包括：jstlView、freemarkerView、pdfView等。我们最常用的视图就是 jsp。
     * 一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户，需要由程序员根据业务需求开 发具体的页面。
     *
     * @see View#render(Map, HttpServletRequest, HttpServletResponse)
     */
    public void view() {
    }

}
